﻿using EventArgs = System.EventArgs;

namespace LightCAD.Model
{
    public class InputResult3d
    {
        public object ValueX { get; set; }
        public string Option { get; set; }
        public object Extent { get; set; }
        public bool IsCancelled { get; set; }

        public InputResult3d()
        {
        }
        public InputResult3d(object value, string option)
        {
            ValueX = value;
            Option = option;
        }
        public InputResult3d(object value, string option, object extent)
        {
            this.ValueX = value;
            this.Option = option;
            this.Extent = extent;
        }

    }
    public class Inputer3d :IDisposable
    {
        protected CancellationTokenSource cts;
        protected bool isInputed;
        public bool isCancelled;
        protected DocumentRuntime docRt;
        protected Model3DEditRuntime modelEditRt;
        protected IDocumentEditor docEditor;
        protected ICommandControl commandCtrl;

        protected Inputer3d(IDocumentEditor docEditor)
        {
            this.docEditor= docEditor;  
            this.docRt = docEditor.DocRt;
            this.modelEditRt = docEditor as Model3DEditRuntime;
            this.commandCtrl = this.modelEditRt.CommandCenter.Commander;
        }
        protected void AttachEvents()
        {
            this.modelEditRt.Control.AttachEvents(OnRuntimeInit, OnRuntimeDestory,
               this.OnRuntimeMouseEvent, this.OnRuntimeKeyDown, this.OnRuntimeKeyUp, null, null
            );
            this.commandCtrl.AttachInputEvent(OnInputBoxKeyDown, OnInputBoxKeyUp,OnInputGotFocus,OnInputLossFocus);
        }

        protected void DetachEvents()
        {
            this.modelEditRt.Control.DetachEvents(OnRuntimeInit, OnRuntimeDestory,
               this.OnRuntimeMouseEvent, this.OnRuntimeKeyDown, this.OnRuntimeKeyUp, null, null
             );
            this.commandCtrl.DetachInputEvent(OnInputBoxKeyDown, OnInputBoxKeyUp, OnInputGotFocus, OnInputLossFocus);
        }

        protected virtual void OnRuntimeInit() 
        {
        }
        protected virtual void OnRuntimeDestory() 
        {
        }
        #region MouseEvent
        protected virtual void OnRuntimeMouseEvent(string type, MouseEventRuntime e)
        {
            if (type == "Down") OnRuntimeMouseDown(e);
            else if (type == "Move") OnRuntimeMouseMove(e);
            else if (type == "Up") OnRuntimeMouseUp(e);
            else if (type == "Wheel") OnRuntimeMouseWheel(e);
            else if (type == "HoverStart") OnRuntimeMouseHoverStart(e);
            else if (type == "HoverEnd") OnRuntimeMouseHoverEnd(e);
        }
        protected virtual void OnRuntimeMouseHoverStart(MouseEventRuntime e)
        {
        }
        protected virtual void OnRuntimeMouseHoverEnd(MouseEventRuntime e)
        {
        }
        protected virtual void OnRuntimeMouseDown(MouseEventRuntime e)
        {
        }
        protected virtual void OnRuntimeMouseMove(MouseEventRuntime e)
        {
        }
        protected virtual void OnRuntimeMouseUp(MouseEventRuntime e)
        {
        }
        protected virtual void OnRuntimeMouseWheel(MouseEventRuntime e)
        {
        }
        #endregion MouseEvent

        protected virtual void OnRuntimeKeyDown(KeyEventRuntime e)
        {
             if(e.KeyCode == 27 || e.KeyCode==13 || e.KeyCode == 32)//Escape /Enter /Space
            {
                OnInputBoxKeyDown(new KeyEventRuntime { KeyCode=e.KeyCode, KeyModifiers=e.KeyModifiers });
            }
        }
        protected virtual void OnRuntimeKeyUp(KeyEventRuntime e) 
        { }

        protected virtual void OnInputBoxKeyDown(KeyEventRuntime e)
        {
            if (e.KeyCode == 27)//Keys.Escape
            {
                this.Cancel();
            }
            else if (e.KeyCode == 13 || e.KeyCode == 32) 
            {
                var text = this.commandCtrl.GetInputText().Trim();
                var prompt = this.commandCtrl.GetPrompt().Trim();
                WriteInfo(prompt, text);
            }
        }
        protected virtual void OnInputBoxKeyUp(KeyEventRuntime e)
        {
        }
        public virtual void OnInputGotFocus(ICommandControl control, EventArgs args)
        {
        }
        public virtual void OnInputLossFocus(ICommandControl control, EventArgs args)
        {
        }
        protected async Task WaitFinish()
        {
            cts = new CancellationTokenSource();
            await Task.Run(() =>
            {
                while (!cts.Token.IsCancellationRequested && !isInputed)
                {
                }
            }, cts.Token);
        }

        protected void Finish()
        {
            this.isInputed = true;
        }
        protected void Cancel()
        {
            this.isCancelled = true;
            this.cts.Cancel();
        }
        public void Prompt(string prompt)
        {
            this.commandCtrl.Prompt(prompt);
        }
        public void WriteInfo(string prompt,string input = "", string result="")
        {
            this.commandCtrl.WriteInfo(prompt+ input + result);
        }
        public void Reset()
        {
            this.isCancelled = false;
            this.isInputed = false;
        }

        public void Dispose()
        {
            this.docEditor = null;
            this.docRt = null;
            this.commandCtrl = null;
        }
    }
  
  
 
    
   
}
